﻿using Autofac;
using DJY.Code;
using DJY.Code.Enums;
using DJY.Domain.Entity.SystemManage;
using DJY.Domain.Entity.SystemSecurity;
using DJY.Domain.IRepository.SystemManage;
using DJY.Domain.IRepository.SystemSecurity;
using DJY.Domain.ViewModel;
using DJY.Domain.ViewModel.SystemManage;
using DJY.Service.SystemManage;
using DJY.Service.SystemSecurity;
using System;
using System.Collections.Generic;
using System.Data.Common;
using System.Data.Entity;
using System.Data.SqlClient;
using System.Linq;
using System.Security.Authentication;

namespace DJY.Application.SystemManage
{
    public class SysUserService : ISysUserService
    {
        static readonly string[] UpdateUserColumns = {
            "F_RealName","F_NickName","F_HeadIcon","F_Birthday","F_Gender","F_MobilePhone",
            "F_Email","F_WeChat","F_SecurityLevel","F_Signature","F_DepartmentId","F_RoleId",
            "F_DutyId","F_IsAdministrator","F_SortCode","F_Description","F_LastModifyTime","F_LastModifyUserId"
        };

        static readonly string[] UpdateUserLoginColumns = { "F_FirstVisitTime", "F_PreviousVisitTime", "F_LastVisitTime", "F_UserOnLine", "F_LogOnCount" };

        static readonly string[] UpdateUserLogoutColumns = { "F_LastVisitTime", "F_UserOnLine" };

        static readonly string[] UpdateUserPwdColumns = { "F_UserPassword", "F_ChangePasswordDate" };

        static readonly string[] EnableItemColumns = { "F_EnabledMark", "F_LastModifyTime", "F_LastModifyUserId" };

        #region 用户
        /// <summary>
        /// 用户登陆
        /// </summary>
        /// <param name="userName">用户名</param>
        /// <param name="pwd">登陆密码</param>
        /// <returns></returns>
        public SysUserEntity CheckLogin(string userName, string pwd)
        {
            if(string.IsNullOrEmpty(userName) || string.IsNullOrEmpty(pwd))
            {
                throw new ArgumentNullException("用户名密码不匹配");
            }

            using (var scope = OperatorProvider.BeginLifetimeScope(null))
            {
                using (var db = scope.Resolve<DbContext>())
                {
                    var userEntity = db.Set<SysUserEntity>().Where(u => u.F_Account == userName)
                    .LeftOuterJoin(db.Set<SysOrganizeEntity>().Where(o => o.F_CategoryId == 1),
                    u => u.F_OrganizeId, o => o.F_Id, (u, o) => new
                    {
                        u.F_Id,
                        u.F_HeadIcon,
                        u.F_Account,
                        u.F_RealName,
                        u.F_OrganizeId,
                        Organize = o.F_FullName,
                        u.F_DepartmentId,
                        u.F_DutyId,
                        u.F_RoleId,
                        u.F_UserType,
                        u.F_EnabledMark,
                    }).LeftOuterJoin(db.Set<SysOrganizeEntity>().Where(d => d.F_CategoryId == 2),
                    u => u.F_DepartmentId, d => d.F_Id, (u, d) => new
                    {
                        u.F_Id,
                        u.F_HeadIcon,
                        u.F_Account,
                        u.F_RealName,
                        u.F_OrganizeId,
                        u.Organize,
                        u.F_DepartmentId,
                        Department = d.F_FullName,
                        u.F_DutyId,
                        u.F_RoleId,
                        u.F_UserType,
                        u.F_EnabledMark
                    }).LeftOuterJoin(db.Set<SysRoleEntity>().Where(r => r.F_CategoryId == 1),
                    u => u.F_RoleId, r => r.F_Id, (u, r) => new
                    {
                        u.F_Id,
                        u.F_HeadIcon,
                        u.F_Account,
                        u.F_RealName,
                        u.F_OrganizeId,
                        u.Organize,
                        u.F_DepartmentId,
                        u.Department,
                        u.F_DutyId,
                        u.F_RoleId,
                        Role = r.F_FullName,
                        u.F_UserType,
                        u.F_EnabledMark,
                    }).LeftOuterJoin(db.Set<SysRoleEntity>().Where(p => p.F_CategoryId == 2),
                    u => u.F_DutyId, p => p.F_Id, (u, p) => new
                    {
                        u.F_Id,
                        u.F_HeadIcon,
                        u.F_Account,
                        u.F_RealName,
                        u.F_OrganizeId,
                        u.Organize,
                        u.F_DepartmentId,
                        u.Department,
                        u.F_DutyId,
                        Duty = p.F_FullName,
                        u.F_RoleId,
                        u.Role,
                        u.F_UserType,
                        u.F_EnabledMark
                    }).FirstOrDefault();
                    if (userEntity == null)
                    {
                        throw new AuthenticationException("账号不存在");
                    }

                    if (!userEntity.F_EnabledMark)
                    {
                        throw new AuthenticationException("用户不可用");
                    }

                    SysUserLogOnEntity logon = db.Set<SysUserLogOnEntity>()
                        .Where(u => u.F_UserId == userEntity.F_Id).FirstOrDefault();
                    if (logon == null)
                    {
                        throw new AuthenticationException("用户名密码不匹配");
                    }

                    if (!Md5.md5(logon.F_UserSecretkey + pwd, 32)
                        .Equals(logon.F_UserPassword, StringComparison.OrdinalIgnoreCase))
                    {
                        throw new AuthenticationException("用户名密码不匹配");
                    }

                    if (logon.F_LockEndDate.HasValue && logon.F_LockEndDate >= DateTime.Now)
                    {
                        throw new AuthenticationException("用户被锁定");
                    }

                    if ((logon.F_AllowStartTime.HasValue && logon.F_AllowStartTime >= DateTime.Now)
                        || (logon.F_AllowEndTime.HasValue && logon.F_AllowEndTime < DateTime.Now))
                    {
                        throw new AuthenticationException("禁止访问");
                    }

                    if (!logon.F_FirstVisitTime.HasValue)
                    {
                        logon.F_FirstVisitTime = DateTime.Now;
                    }
                    logon.F_PreviousVisitTime = logon.F_LastVisitTime;
                    logon.F_LastVisitTime = DateTime.Now;
                    logon.F_UserOnLine = true;
                    logon.F_LogOnCount++;

                    ISysUserLogOnRepository repos = OperatorProvider.Resolve<ISysUserLogOnRepository>();
                    repos.Update(db, UpdateUserLoginColumns, logon);

                    return new SysUserEntity()
                    {
                        F_Id = userEntity.F_Id,
                        F_HeadIcon = userEntity.F_HeadIcon,
                        F_Account = userEntity.F_Account,
                        F_RealName = userEntity.F_RealName,
                        F_OrganizeId = userEntity.F_OrganizeId,
                        Organize = userEntity.Organize,
                        F_DepartmentId = userEntity.F_DepartmentId,
                        Department = userEntity.Department,
                        F_DutyId = userEntity.F_DutyId,
                        Duty = userEntity.Duty,
                        F_RoleId = userEntity.F_RoleId,
                        Role = userEntity.Role,
                        F_UserType = userEntity.F_UserType
                    };
                }
            }
        }

        /// <summary>
        /// 用户退出更新访问时间
        /// </summary>
        /// <param name="userId">用户ID</param>
        /// <returns></returns>
        public int UserLogout(string userId)
        {
            using (var scope = OperatorProvider.BeginLifetimeScope(null))
            {
                using (var db = scope.Resolve<DbContext>())
                {
                    SysUserEntity user = db.Set<SysUserEntity>().Where(u => u.F_Id == userId).FirstOrDefault();
                    if (user == null)
                    {
                        return 0;
                    }

                    SysUserLogOnEntity logon = db.Set<SysUserLogOnEntity>().Where(u => u.F_UserId == userId).FirstOrDefault();
                    if (logon == null)
                    {
                        return 0;
                    }

                    SysLogEntity log = new SysLogEntity();
                    log.F_Id = Guid.NewGuid().ToString();
                    log.F_Date = DateTime.Now;
                    log.F_Type = DbLogType.Logout.ToString();
                    log.F_CreatorTime = DateTime.Now;
                    log.F_CreatorUserId = userId;
                    log.F_Account = user.F_Account;
                    log.F_Result = true;

                    ISysLogRepository logRepos = OperatorProvider.Resolve<ISysLogRepository>();
                    logRepos.Insert(db, log);

                    logon.F_LastVisitTime = DateTime.Now;
                    logon.F_UserOnLine = false;

                    ISysUserLogOnRepository repos = OperatorProvider.Resolve<ISysUserLogOnRepository>();
                    return repos.Update(db, UpdateUserLogoutColumns, logon);
                }
            }
        }

        /// <summary>
        /// 获取用户登陆后需要展示的数据信息
        /// </summary>
        /// <returns></returns>
        public UserClientData GetClientData(string userId)
        {
            UserClientData userData = new UserClientData();
            using (var scope = OperatorProvider.BeginLifetimeScope(null))
            {
                using (var db = scope.Resolve<DbContext>())
                {
                    var user = db.Set<SysUserEntity>().Where(u => u.F_Id == userId).Select(u => new { 
                        u.F_OrganizeId,
                        u.F_DepartmentId,
                        u.F_RoleId,
                        u.F_DutyId
                    }).FirstOrDefault();

                    if(user == null)
                    {
                        return userData;
                    }

                    List<SysModuleEntity> modules = OperatorProvider.Resolve<ISysService>().GetSysModules(db,user.F_OrganizeId);
                    if(modules.Count>0)
                    {
                        Dictionary<string, SysModuleViewModel> moduleDic = new Dictionary<string, SysModuleViewModel>();
                        userData.authorizeMenu = new List<SysModuleViewModel>();
                        List<SysRoleAuthorizeEntity> roleAuths = GetRoleAuth(db, user.F_RoleId);
                        if(roleAuths.Count>0)
                        {
                            roleAuths.ForEach(ra=> {
                                SysModuleEntity module = modules.FirstOrDefault(m => m.F_Id == ra.F_ItemId);
                                if(module != null && !moduleDic.ContainsKey(module.F_Id))
                                {
                                    SysModuleViewModel menu = module.Map<SysModuleEntity, SysModuleViewModel>();
                                    moduleDic.Add(module.F_Id, menu);
                                    
                                    if (!string.IsNullOrEmpty(module.F_ParentId) && module.F_ParentId != "0")
                                    {
                                        SysModuleEntity parent = modules.FirstOrDefault(m => m.F_Id == module.F_ParentId);
                                        if(parent != null)
                                        {
                                            SysModuleViewModel parentMenu = null;
                                            if (!moduleDic.ContainsKey(parent.F_Id))
                                            {
                                                parentMenu = parent.Map<SysModuleEntity, SysModuleViewModel>();
                                                moduleDic.Add(parent.F_Id, parentMenu);
                                                parentMenu.children = new List<SysModuleViewModel>();
                                                userData.authorizeMenu.Add(parentMenu);
                                            }
                                            else
                                            {
                                                parentMenu = moduleDic[parent.F_Id];
                                            }

                                            parentMenu.children.Add(menu);
                                        }
                                    }
                                    else
                                    {
                                        userData.authorizeMenu.Add(menu);
                                    }
                                }
                            });
                        }
                    }
                }
            }
            return userData;
        }

        /// <summary>
        /// 用户查询
        /// </summary>
        /// <param name="queryInfo">查询信息</param>
        /// <returns></returns>
        public PagedResult QueryUser(UserQueryInfo queryInfo)
        {
            if (queryInfo == null || string.IsNullOrEmpty(queryInfo.userId))
            {
                return PagedResult.Empty;
            }

            int total = 0;
            List<SysUserEntity> rows = null;
            using (var scope = OperatorProvider.BeginLifetimeScope(null))
            {
                using (var db = scope.Resolve<DbContext>())
                {
                    var search = db.Set<SysUserEntity>().Where(u => u.F_OrganizeId == queryInfo.companyId)
                        .Join(db.Set<SysUserLogOnEntity>(), u => u.F_Id, ul => ul.F_UserId, (u, ul) => new
                        {
                            u.F_Id,
                            u.F_HeadIcon,
                            u.F_Account,
                            u.F_RealName,
                            u.F_NickName,
                            u.F_Gender,
                            u.F_Email,
                            u.F_MobilePhone,
                            u.F_DepartmentId,
                            u.F_DutyId,
                            u.F_RoleId,
                            u.F_UserType,
                            u.F_EnabledMark,
                            u.F_CreatorTime,
                            ul.F_PreviousVisitTime,
                            u.F_SortCode
                        })
                        .LeftOuterJoin(db.Set<SysOrganizeEntity>().Where(d => d.F_CategoryId == 2),
                        u => u.F_DepartmentId, d => d.F_Id, (u, d) => new
                        {
                            u.F_Id,
                            u.F_HeadIcon,
                            u.F_Account,
                            u.F_RealName,
                            u.F_NickName,
                            u.F_Gender,
                            u.F_Email,
                            u.F_MobilePhone,
                            u.F_DepartmentId,
                            Department = d.F_FullName,
                            u.F_DutyId,
                            u.F_RoleId,
                            u.F_UserType,
                            u.F_EnabledMark,
                            u.F_CreatorTime,
                            u.F_PreviousVisitTime,
                            u.F_SortCode
                        }).LeftOuterJoin(db.Set<SysRoleEntity>().Where(r => r.F_CategoryId == 1),
                        u => u.F_RoleId, r => r.F_Id, (u, r) => new
                        {
                            u.F_Id,
                            u.F_HeadIcon,
                            u.F_Account,
                            u.F_RealName,
                            u.F_NickName,
                            u.F_Gender,
                            u.F_Email,
                            u.F_MobilePhone,
                            u.F_DepartmentId,
                            u.Department,
                            u.F_DutyId,
                            u.F_RoleId,
                            Role = r.F_FullName,
                            u.F_UserType,
                            u.F_EnabledMark,
                            u.F_CreatorTime,
                            u.F_PreviousVisitTime,
                            u.F_SortCode
                        }).LeftOuterJoin(db.Set<SysRoleEntity>().Where(p => p.F_CategoryId == 2),
                        u => u.F_DutyId, p => p.F_Id, (u, p) => new
                        {
                            u.F_Id,
                            u.F_HeadIcon,
                            u.F_Account,
                            u.F_RealName,
                            u.F_NickName,
                            u.F_Gender,
                            u.F_Email,
                            u.F_MobilePhone,
                            u.F_DepartmentId,
                            u.Department,
                            u.F_DutyId,
                            Duty = p.F_FullName,
                            u.F_RoleId,
                            u.Role,
                            u.F_UserType,
                            u.F_EnabledMark,
                            u.F_CreatorTime,
                            u.F_PreviousVisitTime,
                            u.F_SortCode
                        });

                    if(!string.IsNullOrEmpty(queryInfo.keyword))
                    {
                        search = search.Where(u => u.F_RealName == queryInfo.keyword
                        || u.F_NickName.Contains(queryInfo.keyword)
                        || u.F_Email == queryInfo.keyword
                        || u.F_MobilePhone == queryInfo.keyword);
                    }

                    if(!string.IsNullOrEmpty(queryInfo.department))
                    {
                        search = search.Where(u => u.F_DepartmentId == queryInfo.department);
                    }

                    if (!string.IsNullOrEmpty(queryInfo.role))
                    {
                        search = search.Where(u => u.F_RoleId == queryInfo.role);
                    }

                    if (!string.IsNullOrEmpty(queryInfo.duty))
                    {
                        search = search.Where(u => u.F_DutyId == queryInfo.duty);
                    }

                    total = search.Count();

                    rows = search.OrderBy(c => c.F_SortCode)
                        .Skip((queryInfo.page - 1) * queryInfo.rows)
                        .Take(queryInfo.rows).ToList().Select(u => new SysUserEntity {
                            F_Id = u.F_Id,
                            F_HeadIcon = u.F_HeadIcon,
                            F_Account = u.F_Account,
                            F_RealName = u.F_RealName,
                            F_NickName = u.F_NickName,
                            F_Gender = u.F_Gender,
                            F_Email = u.F_Email,
                            F_MobilePhone = u.F_MobilePhone,
                            F_DepartmentId = u.F_DepartmentId,
                            Department = u.Department,
                            F_DutyId = u.F_DutyId,
                            Duty = u.Duty,
                            F_RoleId = u.F_RoleId,
                            Role = u.Role,
                            F_UserType = u.F_UserType,
                            F_EnabledMark = u.F_EnabledMark,
                            F_CreatorTime = u.F_CreatorTime,
                            LastVisitTime = u.F_PreviousVisitTime
                        }).ToList();
                }
            }

            return new PagedResult()
            {
                records = total,
                total = (int)Math.Ceiling((float)total / queryInfo.rows),
                page = queryInfo.page,
                rows = rows
            };
        }

        /// <summary>
        /// 筛选下拉用户信息
        /// </summary>
        /// <param name="queryInfo">查询条件</param>
        public PagedResult SelectUserPageList(HtmlSelectQueryInfo queryInfo)
        {
            using (var scope = OperatorProvider.BeginLifetimeScope(null))
            {
                using (var db = scope.Resolve<DbContext>())
                {
                    PagedResult result = new PagedResult();
                    var userSet = db.Set<SysUserEntity>().Where(u => u.F_EnabledMark && u.F_Account != "admin");
                    if (!string.IsNullOrEmpty(queryInfo.keyword))
                    {
                        userSet = userSet.Where(u => u.F_RealName == queryInfo.keyword
                        || u.F_NickName.Contains(queryInfo.keyword)
                        || u.F_MobilePhone == queryInfo.keyword
                        || u.F_Email == queryInfo.keyword);
                    }

                    var search = userSet.Join(db.Set<SysOrganizeEntity>().Where(o => o.F_EnabledMark),
                        u => u.F_DepartmentId, o => o.F_Id, (u, o) => new
                        {
                            u.F_CreatorTime,
                            UserName = u.F_RealName ?? u.F_NickName,
                            UserId = u.F_Id,
                            DepartId = u.F_DepartmentId,
                            Depart = o.F_FullName
                        });

                    result.total = search.Count();
                    result.rows = search.OrderBy(u => u.F_CreatorTime).Skip((queryInfo.page - 1) * queryInfo.rows)
                        .Take(queryInfo.rows)
                        .ToList().Select(u => new UserSelectListModel()
                        {
                            userId = u.UserId,
                            userName = u.UserName,
                            depart = u.Depart
                        }).ToList();

                    return result;
                }
            }
        }

        /// <summary>
        /// 修改用户密码
        /// </summary>
        /// <param name="userId">用户</param>
        /// <param name="pwd">新密码</param>
        /// <param name="opMan">操作人</param>
        /// <returns></returns>
        public EditItemResult UpdateUserPwd(string userId, string pwd, string opMan)
        {
            using (var scope = OperatorProvider.BeginLifetimeScope(null))
            {
                using (var db = scope.Resolve<DbContext>())
                {

                    SysUserEntity userEntity = db.Set<SysUserEntity>().Where(u => u.F_Id == userId).FirstOrDefault();
                    if (userEntity == null)
                    {
                        return EditItemResult.Fail("用户不存在");
                    }

                    DbContextTransaction trans = db.Database.BeginTransaction();
                    try
                    {
                        if (string.IsNullOrEmpty(pwd))
                        {
                            pwd = "123456";
                        }
                        SysUserLogOnEntity logon = db.Set<SysUserLogOnEntity>().Where(l => l.F_UserId == userId).FirstOrDefault();
                        logon.F_UserPassword = Md5.md5(logon.F_UserSecretkey + pwd, 32);
                        logon.F_ChangePasswordDate = DateTime.Now;
                        ISysUserLogOnRepository logonRepos = OperatorProvider.Resolve<ISysUserLogOnRepository>();
                        logonRepos.Update(db, UpdateUserPwdColumns, logon);

                        SysLogEntity log = new SysLogEntity();
                        log.F_Id = Guid.NewGuid().ToString();
                        log.F_Date = DateTime.Now;
                        log.F_Type = DbLogType.UpdatePwd.ToString();
                        log.F_CreatorTime = DateTime.Now;
                        log.F_CreatorUserId = opMan;
                        log.F_Account = userEntity.F_Account;
                        log.F_Result = true;

                        ISysLogRepository logRepos = OperatorProvider.Resolve<ISysLogRepository>();
                        logRepos.Insert(db, log);

                        trans.Commit();
                        return EditItemResult.Ok();
                    }
                    catch (Exception ex)
                    {
                        trans.Rollback();
                        return EditItemResult.Fail(Common.ShowException(ex));
                    }
                }
            }
        }

        /// <summary>
        /// 保存用户信息
        /// </summary>
        /// <param name="user">用户</param>
        public EditItemResult SaveUser(SysUserEntity user)
        {
            using (var scope = OperatorProvider.BeginLifetimeScope(null))
            {
                using (var db = scope.Resolve<DbContext>())
                {
                    if (string.IsNullOrEmpty(user.F_Id))
                    {
                        EditItemResult result = CheckAddUserResult(db,user);
                        if(result != null)
                        {
                            return result;
                        }

                        DbContextTransaction trans = db.Database.BeginTransaction();

                        try
                        {
                            ISysUserRepository repos = OperatorProvider.Resolve<ISysUserRepository>();
                            user.F_Id = Guid.NewGuid().ToString();
                            repos.Insert(db, user);

                            if (string.IsNullOrEmpty(user.Pwd))
                            {
                                user.Pwd = "123456";
                            }

                            SysUserLogOnEntity logon = new SysUserLogOnEntity();
                            logon.F_UserId = user.F_Id;
                            logon.F_UserSecretkey = user.F_Id.Substring(24, 12);
                            logon.F_UserPassword = Md5.md5(logon.F_UserSecretkey + user.Pwd, 32);
                            ISysUserLogOnRepository logonRepos = OperatorProvider.Resolve<ISysUserLogOnRepository>();
                            logonRepos.Insert(db, logon);

                            trans.Commit();
                            return EditItemResult.Ok();
                        }
                        catch(Exception ex)
                        {
                            trans.Rollback();
                            return EditItemResult.Fail(Common.ShowException(ex));
                        }
                    }
                    else
                    {
                        EditItemResult result = CheckUpdateUserResult(db, user);
                        if (result != null)
                        {
                            return result;
                        }

                        SysUserEntity userEntity = db.Set<SysUserEntity>().Where(u => u.F_Id == user.F_Id).FirstOrDefault();
                        if(userEntity == null)
                        {
                            return EditItemResult.Fail("用户不存在");
                        }

                        DbContextTransaction trans = db.Database.BeginTransaction();

                        try
                        {
                            ISysUserRepository repos = OperatorProvider.Resolve<ISysUserRepository>();
                            repos.Update(db, UpdateUserColumns, user);

                            if (!string.IsNullOrEmpty(user.Pwd))
                            {
                                SysUserLogOnEntity logon = db.Set<SysUserLogOnEntity>().Where(l => l.F_UserId == user.F_Id).FirstOrDefault();
                                logon.F_UserPassword = Md5.md5(logon.F_UserSecretkey + user.Pwd, 32);
                                logon.F_ChangePasswordDate = DateTime.Now;

                                ISysUserLogOnRepository logonRepos = OperatorProvider.Resolve<ISysUserLogOnRepository>();
                                logonRepos.Update(db, UpdateUserPwdColumns, logon);

                                SysLogEntity log = new SysLogEntity();
                                log.F_Id = Guid.NewGuid().ToString();
                                log.F_Date = DateTime.Now;
                                log.F_Type = DbLogType.UpdatePwd.ToString();
                                log.F_CreatorTime = DateTime.Now;
                                log.F_CreatorUserId = user.F_CreatorUserId;
                                log.F_Account = user.F_Account;
                                log.F_Result = true;

                                ISysLogRepository logRepos = OperatorProvider.Resolve<ISysLogRepository>();
                                logRepos.Insert(db, log);
                            }

                            trans.Commit();
                            return EditItemResult.Ok();
                        }
                        catch (Exception ex)
                        {
                            trans.Rollback();
                            return EditItemResult.Fail(Common.ShowException(ex));
                        }
                    }
                }
            }
        }

        /// <summary>
        /// 禁用启用
        /// </summary>
        /// <param name="ids">键列表</param>
        /// <param name="state">状态</param>
        /// <param name="userId">操作用户ID</param>
        /// <returns>操作结果</returns>
        public EditItemResult EnableUser(List<string> ids, bool state, string userId)
        {
            if (ids == null)
            {
                throw new ArgumentNullException(nameof(ids));
            }

            if (ids.Count == 0 || string.IsNullOrEmpty(userId))
            {
                return EditItemResult.Ok();
            }

            using (var scope = OperatorProvider.BeginLifetimeScope(null))
            {
                using (var db = scope.Resolve<DbContext>())
                {
                    List<SysUserEntity> list = db.Set<SysUserEntity>()
                    .Where(u => ids.Contains(u.F_Id) && u.F_EnabledMark != state)
                    .Select(u => new {
                        u.F_Id,
                        u.F_EnabledMark
                    })
                    .ToList()
                    .Select(u => new SysUserEntity()
                    {
                        F_Id = u.F_Id,
                        F_EnabledMark = state,
                        F_LastModifyTime = DateTime.Now,
                        F_LastModifyUserId = userId
                    }).ToList();

                    int count = 0;
                    if (list.Count > 0)
                    {
                        ISysUserRepository repo = OperatorProvider.Resolve<ISysUserRepository>();
                        count = repo.Update(db, EnableItemColumns, list);
                    }

                    return EditItemResult.Ok(null, count.ToString());
                }
            }
        }

        /// <summary>
        /// 检查添加用户信息
        /// </summary>
        /// <param name="user">用户信息</param>
        /// <returns></returns>
        private EditItemResult CheckAddUserResult(DbContext db,SysUserEntity user)
        {
            if (string.IsNullOrEmpty(user.F_Account))
            {
                return EditItemResult.Fail("账号不能为空");
            }

            if (string.IsNullOrEmpty(user.F_RealName))
            {
                return EditItemResult.Fail("姓名不能为空");
            }

            if (string.IsNullOrEmpty(user.F_NickName))
            {
                return EditItemResult.Fail("昵称不能为空");
            }

            if(db.Set<SysUserEntity>().Any(u=>u.F_Account == user.F_Account))
            {
                return EditItemResult.Fail("账号已存在");
            }

            if (string.IsNullOrEmpty(user.F_OrganizeId))
            {
                return EditItemResult.Fail("未选择单位");
            }

            if (string.IsNullOrEmpty(user.F_DepartmentId))
            {
                return EditItemResult.Fail("未选择部门");
            }

            return null;
        }

        /// <summary>
        /// 检查添加用户信息
        /// </summary>
        /// <param name="user">用户信息</param>
        /// <returns></returns>
        private EditItemResult CheckUpdateUserResult(DbContext db, SysUserEntity user)
        {
            if (string.IsNullOrEmpty(user.F_RealName))
            {
                return EditItemResult.Fail("姓名不能为空");
            }

            if (string.IsNullOrEmpty(user.F_NickName))
            {
                return EditItemResult.Fail("昵称不能为空");
            }

            if (string.IsNullOrEmpty(user.F_DepartmentId))
            {
                return EditItemResult.Fail("未选择部门");
            }

            return null;
        }
        #endregion

        #region 角色
        /// <summary>
        /// 获取角色授权信息
        /// </summary>
        /// <param name="roleId">角色ID</param>
        /// <param name="itemType">授权类型 1模块 2按钮 3列表</param>
        /// <returns></returns>
        public List<SysRoleAuthorizeEntity> GetRoleAuth(string roleId, int itemType = 1)
        {
            string key = string.Format(CacheKeys.Role_Auths, roleId, itemType);
            List<SysRoleAuthorizeEntity> list = OperatorProvider.GetCache<List<SysRoleAuthorizeEntity>>(key);
            if (list == null)
            {
                using (var scope = OperatorProvider.BeginLifetimeScope(null))
                {
                    using (var db = scope.Resolve<DbContext>())
                    {
                        list = GetRoleAuth(db, roleId);

                        if (list.Count > 0)
                        {
                            OperatorProvider.SetCache(key, list);
                        }
                    }
                }
            }

            return list;
        }

        /// <summary>
        /// 获取角色授权信息
        /// </summary>
        /// <param name="db">数据库实例</param>
        /// <param name="roleId">角色ID</param>
        /// <param name="itemType">授权类型 1模块 2按钮 3列表</param>
        /// <returns></returns>
        public List<SysRoleAuthorizeEntity> GetRoleAuth(DbContext db,string roleId,int itemType = 1)
        {
            if (db == null)
            {
                return GetRoleAuth(roleId);
            }

            string key = string.Format(CacheKeys.Role_Auths, roleId, itemType);
            List<SysRoleAuthorizeEntity> list = OperatorProvider.GetCache<List<SysRoleAuthorizeEntity>>(key);
            if (list == null)
            {
                list = db.Set<SysRoleAuthorizeEntity>().Where(ra=>ra.F_ObjectId == roleId 
                && ra.F_ObjectType == 1
                && ra.F_ItemType == itemType).ToList();

                if (list.Count > 0)
                {
                    OperatorProvider.SetCache(key, list);
                }
            }
            return list;
        }
        #endregion
    }
}
